package users

import (
	"fmt"
	"go_auth/ext/e"
	"go_auth/ext/settings"
	"go_auth/utils/commons"
	"go_auth/utils/mysql"
	"strconv"
	"time"
)

/**
用户信息
	系统用户有一个账户可以添加设置用户信息
	必须添加字段
*/

type User struct {
	Uid      string `xorm:"pk notnull unique varchar(100) 'uid'"` //用户id
	UserName string //用户姓名
	UserNick string `xorm:"varchar(200) 'user_nick' "` //用户昵称
	Password string `xorm:"varchar(200) 'password' "`  //密码
	//Source      string    `xorm:"varchar(200) 'source' "`             //来源
	CompanyId   string    `xorm:"varchar(200) 'company_id' "`
	Phone       string    `xorm:"varchar(200) 'phone' "` //用户电话
	Email       string    `xorm:"varchar(200) 'email' "`
	Staff       int       `xorm:"int(4) 'staff' default -1 "`          //是否可以返回权限列表 -1表示不可以
	Status      int       `xorm:"int(4) not null default 1 'status'"`  //用户是否禁用   1表示没有被禁用 -1表示禁用
	IsLock      int       `xorm:"int(4) not null default 1 'is_lock'"` //用户是否锁住   1表示没有被锁住 -1表示锁住
	LockTime    string    `xorm:"varchar(60) 'lock_time'"`             //锁住时间
	ExpireTime  string    `xorm:"varchar(60) 'expire_time'"`           //试用账户(默认3天)(页面展示是正常日期，计算的时候化成时间戳)
	CreateTime  time.Time `xorm:"created 'create_time' "  `
	UpdatedTime time.Time `xorm:"updated 'update_time'"`
}

/**
注册用户之前先查看这个用户是够存在

用户注册的默认赋予的是角色权限
TODO   v0.2 手机号码登录
*/
func Register(username, password, sourceId string) int64 {

	uid := commons.EncodeMd5(username + password + sourceId + settings.JwtBase.JwtSecret)

	//如果sourceUser映射表中没有数据，说明这个用户没有注册
	sourceByUid := ExistUserSourceByUid(uid)
	if sourceByUid != settings.Empty {
		return e.UserExist
	}
	a := time.Now()
	location, _ := time.LoadLocation("Local")
	date := a.In(location).AddDate(0, 0, 10)
	user := User{UserName: username, Password: password, Uid: uid, ExpireTime: date.Format("2006-01-02 15:04:05")}
	role := UserRole{Uid: uid, RoleId: 1}
	rolePer := RolePer{RoleId: 1, PerId: 1}
	userSource := UserSource{Uid: uid, SourceId: sourceId}

	s := settings.MasterDB.NewSession()

	var err error
	if err = s.Begin(); err != nil {
		return e.Error
	}
	defer s.Rollback()
	if !(mysql.CheckErrInsert(s, user) && mysql.CheckErrInsert(s, role) && mysql.CheckErrInsert(s, rolePer) && mysql.CheckErrInsert(s, userSource)) {
		return e.AddError
	}
	s.Commit()
	s.Close()
	return e.Success
}

type LoginGroup struct {
	Uid        string
	SourceId   string
	Staff      string
	Status     string
	ExpireTime string
}

func Login(username, password, sourceId string) (int, string, string, int, bool) {
	//sql := fmt.Sprintf("SELECT DISTINCT u.uid,us.source_id, u.staff,u.status,u.expire_time FROM  "+
	//	"user_source us,`user` u,`source` s WHERE s.source_id=us.source_id AND u.user_name='%s' "+
	//	"AND u.password = '%s' AND us.source_id= '%s'", username, password, sourceId)
	//query, err := settings.MasterDB.QueryString(sql)
	//var group []LoginGroup

	group := make([]LoginGroup, 0)
	count, err := settings.MasterDB.Table(commons.StringJoin([]string{settings.PrefixTable, "user"})).Alias("u").
		Select("u.uid,us.source_id, u.staff,u.status,u.expire_time").
		Join("INNER", []string{commons.StringJoin([]string{settings.PrefixTable, "user_source"}), "us"}, "u.uid=us.uid").
		Join("INNER", []string{commons.StringJoin([]string{settings.PrefixTable, "source"}), "s"}, "s.source_id=us.source_id").
		Where(" u.user_name = ? and   u.password = ? and us.source_id= ? ", username, password, sourceId).
		FindAndCount(&group)

	toi := 0
	fmt.Println(group)
	if !commons.CheckErr(err) {
		return toi, settings.StringFlag, settings.Empty, e.Error, false
	}
	if count < 1 {
		return toi, settings.StringFlag, settings.Empty, e.UserNotExist, false
	}
	if toInt, b := commons.StrToInt(group[0].Status); b {
		//表示用户被禁止访问
		if toInt == -1 {
			return toi, settings.StringFlag, settings.Empty, e.UserForbid, false
		}
	}

	toi, _ = strconv.Atoi(group[0].Staff)
	a := time.Now()
	location, _ := time.LoadLocation("Local")
	code := e.Success
	flag := true

	p, _ := time.ParseInLocation("2006-01-02 15:04:05", group[0].ExpireTime, location)

	if a.In(location).Unix()-p.In(location).Unix() >= 0 {
		code = e.UserExpireTimeout
		flag = false
	}

	return toi, group[0].SourceId, group[0].Uid, code, flag

}

/**
用户列表
*/

type Group struct {
	Uid        string
	UserName   string
	Staff      int
	Status     int
	ExpireTime string
	RoleName   string
	SourceName string
	SourceOp   string
}

func FindUsers(size int) (interface{}, int64) {
	var group []Group
	count, err := settings.MasterDB.Table(commons.StringJoin([]string{settings.PrefixTable, "user"})).Alias("u").
		Select("u.uid,u.user_name,u.staff,u.company_id,u.status,u.expire_time,r.role_name,s.source_name,s.source_op").
		Join("INNER", []string{commons.StringJoin([]string{settings.PrefixTable, "user_role"}), "ur"}, "ur.uid=u.uid").
		Join("INNER", []string{commons.StringJoin([]string{settings.PrefixTable, "role"}), "r"}, "r.role_id = ur.role_id").
		Join("INNER", []string{commons.StringJoin([]string{settings.PrefixTable, "user_source"}), "us"}, "us.uid = u.uid ").
		Join("INNER", []string{commons.StringJoin([]string{settings.PrefixTable, "source"}), "s"}, "us.source_id = s.source_id ").
		Limit(int(settings.AppBase.PageSize), size*int(settings.AppBase.PageSize)).FindAndCount(&group)

	if !commons.CheckErr(err) {
		return nil, 0
	}
	return group, count
}

/**
修改密码
*/

func (u *User) UpdatePassword() int64 {
	update, err := settings.MasterDB.Where("uid=?", u.Uid).Update(u)

	if commons.CheckErr(err) {
		return update
	}
	return settings.Zero
}

/**
设置为后台管理员
*/

func (u *User) SetAdmin() int64 {
	update, err := settings.MasterDB.Where("uid=?", u.Uid).Update(u)

	if commons.CheckErr(err) {
		return update
	}
	return settings.Zero
}

/**
获取用户权限信息
*/
func GetAllUserPer() ([]map[string]string, error) {
	sql := " select distinct u.`uid`,p.`per_id`,p.method from `web_user` u, `web_user_role` ur, `web_role` r, `web_role_per` rp, `web_per` p " +
		" where u.`status` = 0 and u.`uid` = ur.`uid` and ur.`role_id` = r.`role_id` and ur.`role_id` = rp.`role_id` " +
		" and rp.`per_id` = p.`per_id` " +
		" union select DISTINCT u.`uid`,p.`per_id` ,p.method from `web_user` u, `web_user_per` up,`web_per` p " +
		" where u.`status` = 0 and u.`uid` = up.`uid` and up.`per_id` = p.`per_id` "
	//settings.MasterDB.Table(commons.StringJoin([]string{settings.PrefixTable, "user"})).Alias("u").
	//	Select("u.uid,p.per_id,p.method").
	//	Join("INNER", []string{commons.StringJoin([]string{settings.PrefixTable, "user_role"}), "ur"}, "ur.uid=u.uid").
	//	Join("INNER", []string{commons.StringJoin([]string{settings.PrefixTable, "role"}), "r"}, " ur.role_id = r.role_id").
	//	Join("INNER", []string{commons.StringJoin([]string{settings.PrefixTable, "role_per"}), "rp"}, "ur.role_id = rp.role_id").
	//	Join("INNER", []string{commons.StringJoin([]string{settings.PrefixTable, "p"}), "p"}, "rp.per_id = p.per_id")
	strings, err := settings.MasterDB.QueryString(sql)

	return strings, err
}

//批量导入用户
